package com.trw.trp.action;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.trw.trp.bean.ListBean;
import com.trw.trp.bean.ModelBean;
import com.trw.trp.bean.ModelDetail;
import com.trw.trp.bean.OrderBean;
import com.trw.trp.bean.OrderBean.GeneralInfo;
import com.trw.trp.bean.OrderBean.OrderStatus;
import com.trw.trp.bean.TemplateBean;
import com.trw.trp.bean.UserBean;
import com.trw.trp.dao.DaoFactory;
import com.trw.trp.dao.ListDao;
import com.trw.trp.dao.ModelDao;
import com.trw.trp.dao.OrderDao;
import com.trw.trp.dao.UserDao;
import com.trw.trp.msg.ResultMessage;
import com.trw.trp.util.TRPConstants;
import com.trw.trp.util.TRPUtil;
import com.utuan.log.Log;
import com.utuan.log.LogFactory;
import com.utuan.util.TuanUtil;

public class ModelAction extends AbstractAction {

	private static Log log = LogFactory.getLog(ModelAction.class);

	private String models;
	private String modelIdx;
	private String subModelIds;

	public String getModels() {
		return models;
	}

	public void setModels(String models) {
		this.models = models;
	}

	public String getModelIdx() {
		return modelIdx;
	}

	public void setModelIdx(String modelIdx) {
		this.modelIdx = modelIdx;
	}

	public String getSubModelIds() {
		return subModelIds;
	}

	public void setSubModelIds(String subModelIds) {
		this.subModelIds = subModelIds;
	}

	public String modelChoose() {
		UserBean user = (UserBean) TRPUtil.getFromSession(TRPConstants.CURRENT_USER);
		OrderBean order = (OrderBean) TRPUtil.getFromSession(TRPConstants.CURRENT_ORDER);
		String action = getParamFromRequest("action");
		if ("new".equals(action)) {
			order = new OrderBean();
			order.setUser(user);
			order.setCreatedDate(new Date());
			TRPUtil.putToSession(TRPConstants.CURRENT_ORDER, order);
			TRPUtil.removeFromSession("modelList");
			OrderDao dao = DaoFactory.getOrderDao();
			String orderNumber = dao.getAutoNumber(TRPConstants.AUTO_NUMBER_TRP);
			order.setOrderNumber(orderNumber);
		}
		TRPUtil.putToSession(TRPConstants.CURRENT_MODEL_STATUS, 1);
		return SUCCESS;
	}

	public void goSubModelJson() throws IOException {
		Map<String, Object> map = new HashMap<String, Object>();
		UserBean user = (UserBean) TRPUtil.getFromSession(TRPConstants.CURRENT_USER);
		OrderBean order = (OrderBean) TRPUtil.getFromSession(TRPConstants.CURRENT_ORDER);
		map.put("readOnly", (order == null) || order.isReadOnly(user, OrderStatus.Pipeline));
		writeJSON(map);
	}

	private GeneralInfo getGeneralInfo0() {
		String phase = getParamFromRequest("phaseSelect");
		String customer = getParamFromRequest("customerSelect");
		String product = getParamFromRequest("productSelect");
		String project = getParamFromRequest("projectSelect");
		String plant = getParamFromRequest("plantSelect");
		String reportMode = getParamFromRequest("reportModeSelect");
		String reportDistribution = getParamFromRequest("reportDistrSelect");
		String testUserId = getParamFromRequest("testUserSelect");
		String vvUserId = getParamFromRequest("vvUserSelect");
		String testPurpose = getParamFromRequest("testPurpose");
		String prjNumber = getParamFromRequest("prjNumber");
		String um = getParamFromRequest("um");
		String jrt = getParamFromRequest("jrt");
		String cp = getParamFromRequest("cp");
		String payer = getParamFromRequest("payer");
		OrderBean.GeneralInfo g = new OrderBean.GeneralInfo();
		g.setPhase(phase);
		g.setCustomer(customer);
		g.setProduct(product);
		g.setProject(project);
		g.setPlant(plant);
		g.setReportMode(reportMode);
		g.setReportDistribution(reportDistribution);
		g.setPayer(payer);
		UserDao uDao = DaoFactory.getUserDao();
		if (!StringUtils.isEmpty(testUserId)) {
			try {
				long userId = Long.parseLong(testUserId);
				UserBean testUser = uDao.getUser(userId);
				g.setTestUser(testUser);
			} catch (Exception e) {

			}
		}
		if (!StringUtils.isEmpty(vvUserId)) {
			try {
				long userId = Long.parseLong(vvUserId);
				UserBean vvUser = uDao.getUser(userId);
				g.setVvUser(vvUser);
			} catch (Exception e) {

			}
		}
		g.setTestPurpose(testPurpose);
		g.setProjectNumber(prjNumber);
		g.setUm(um);
		g.setJrt(jrt);
		g.setCp(cp);
		return g;
	}

	public void getGeneralInfo() throws IOException {
		OrderBean.GeneralInfo generalInfo = null;
		OrderBean order = (OrderBean) TRPUtil.getFromSession(TRPConstants.CURRENT_ORDER);
		UserBean user = (UserBean) TRPUtil.getFromSession(TRPConstants.CURRENT_USER);
		if (order != null) {
			generalInfo = order.getGeneralInfo();
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("generalInfo", generalInfo);
		ModelDao dao = DaoFactory.getModelDao();
		List<ModelBean> models = new ArrayList<ModelBean>();
		if (order.getSelectedModels() != null) {
			String[] modelIds = order.getSelectedModels().split(TRPConstants.COMMA);
			for (String modelId : modelIds) {
				try {
					ModelBean mb = dao.getModelById(Integer.parseInt(modelId));
					if (mb != null) {
						models.add(mb);
					}
				} catch (NumberFormatException e) {
					log.warn(e);
				}
			}
		}
		map.put("selectedModels", models);
		map.put("readOnly", order.isReadOnly(user, OrderStatus.Pipeline));
		writeJSON(map);
	}

	public void selectSubModel() throws IOException {
		List<ModelBean> modelList = new ArrayList<ModelBean>();
		boolean flag = false;
		try {
			ModelDao dao = DaoFactory.getModelDao();
			if (models != null) {
				List<String> modelIdList = new ArrayList<String>();
				TRPUtil.putToSession(TRPConstants.CURRENT_MODEL_STATUS, 1);
				String[] modelArr = models.split(TRPConstants.COMMA);
				for (String modelName : modelArr) {
					if (!StringUtils.isEmpty(modelName)) {
						ModelBean model = dao.getModelByName(modelName);
						modelList.add(model);
						modelIdList.add(String.valueOf(model.getModelId()));
					}
				}
				TRPUtil.putToSession("modelList", modelList);

				OrderBean order = (OrderBean) TRPUtil.getFromSession(TRPConstants.CURRENT_ORDER);
				OrderBean.GeneralInfo generalInfo = getGeneralInfo0();
				order.setGeneralInfo(generalInfo);
				order.setSelectedModels(TuanUtil.convertToString(modelIdList));
				autoSaveList(generalInfo);
				OrderDao orderDao = DaoFactory.getOrderDao();
				long orderId = orderDao.saveOrder(order, 1);
				order.setOrderId(orderId);
				TRPUtil.putToSession(TRPConstants.CURRENT_ORDER, order);
				flag = true;
			}
		} catch (Exception e) {
			log.warn(e);
		}
		writeJSON4Form(flag, null);
	}

	private void autoSaveList(OrderBean.GeneralInfo generalInfo) {
		ListDao dao = DaoFactory.getListDao();
		ListBean customerList = dao.getList(1);
		ListBean projectList = dao.getList(2);
		ListBean productList = dao.getList(3);
		ListBean plantList = dao.getList(7);
		// customer list
		ListBean.ItemBean item = new ListBean.ItemBean();
		item.setName(generalInfo.getCustomer());
		if (customerList.getItemList() == null) {
			customerList.setItemList(new ArrayList<ListBean.ItemBean>());
		}
		if (!customerList.getItemList().contains(item)) {
			customerList.getItemList().add(item);
			dao.saveList(customerList);
		}
		// project list
		item = new ListBean.ItemBean();
		item.setName(generalInfo.getProject());
		if (projectList.getItemList() == null) {
			projectList.setItemList(new ArrayList<ListBean.ItemBean>());
		}
		if (!projectList.getItemList().contains(item)) {
			projectList.getItemList().add(item);
			dao.saveList(projectList);
		}
		// product list
		item = new ListBean.ItemBean();
		item.setName(generalInfo.getProduct());
		if (productList.getItemList() == null) {
			productList.setItemList(new ArrayList<ListBean.ItemBean>());
		}
		if (!productList.getItemList().contains(item)) {
			productList.getItemList().add(item);
			dao.saveList(productList);
		}
		// plant list
		item = new ListBean.ItemBean();
		item.setName(generalInfo.getPlant());
		if (plantList.getItemList() == null) {
			plantList.setItemList(new ArrayList<ListBean.ItemBean>());
		}
		if (!plantList.getItemList().contains(item)) {
			plantList.getItemList().add(item);
			dao.saveList(plantList);
		}
	}

	public void updateSubModels() {
		String subModelIds = getParamFromRequest("subModelIds");
		String uniqueIds = getParamFromRequest("uniqueIds");
		ModelDao dao = DaoFactory.getModelDao();
		OrderBean order = (OrderBean) TRPUtil.getFromSession(TRPConstants.CURRENT_ORDER);
		Integer status = (Integer) TRPUtil.getFromSession(TRPConstants.CURRENT_MODEL_STATUS);

		String[] subModelArray = subModelIds.split(TRPConstants.COMMA);
		String[] uniqueIdArray = uniqueIds.split(TRPConstants.COMMA);
		List<ModelBean> modelList = new ArrayList<ModelBean>();
		List<ModelDetail> detailList = new ArrayList<ModelDetail>();
		for (int i = 0; i < subModelArray.length; i++) {
			String subModelId = subModelArray[i];
			String uniqueId = uniqueIdArray[i];
			int idx = -1;
			if (order.getModelMap() == null) {
				order.setModelMap(new HashMap<Integer, List<ModelBean>>());
				order.setDetailMap(new HashMap<Integer, List<ModelDetail>>());
			}
			List<ModelBean> cModelList = order.getModelMap().get(status);
			if (cModelList != null) {
				for (int j = 0; j < cModelList.size(); j++) {
					ModelBean model = cModelList.get(j);
					if (uniqueId.equals(model.getClientUniqueId())) {
						idx = j;
						break;
					}
				}
			}
			ModelBean model = null;
			ModelDetail detail = null;
			if (idx > -1) {
				model = order.getModelMap().get(status).get(idx);
				detail = order.getDetailMap().get(status).get(idx);
			} else {
				long modelId = -1;
				try {
					modelId = Long.parseLong(subModelId);
					model = dao.getModelById(modelId);
					detail = dao.getModelDetail(modelId);
					if (model != null) {
						model.setClientUniqueId(uniqueId);
					}
				} catch (Exception e) {
					log.warn(e);
				}
			}
			if (model != null && detail != null) {
				modelList.add(model);
				detailList.add(detail);
			}
		}

		if (order != null) {
			Map<Integer, List<ModelBean>> modelMap = order.getModelMap();
			Map<Integer, List<ModelDetail>> detailMap = order.getDetailMap();
			if (modelMap == null) {
				modelMap = new HashMap<Integer, List<ModelBean>>();
				order.setModelMap(modelMap);
			}
			modelMap.put(status, modelList);
			if (detailMap == null) {
				detailMap = new HashMap<Integer, List<ModelDetail>>();
				order.setDetailMap(detailMap);
			}
			detailMap.put(status, detailList);
		}
	}

	public void getModelDetail() throws IOException {
		String rowNumberStr = getParamFromRequest("rowNumber");
		ModelDetail detail = null;
		try {
			int idx = Integer.parseInt(rowNumberStr);
			OrderBean order = (OrderBean) TRPUtil.getFromSession(TRPConstants.CURRENT_ORDER);
			if (order != null) {
				Integer status = null;
				try {
					status = new Integer(getParamFromRequest("status"));
				} catch (NumberFormatException e) {

				}
				if (status == null) {
					status = (Integer) TRPUtil.getFromSession(TRPConstants.CURRENT_MODEL_STATUS);
				}
				List<ModelDetail> detailList = order.getDetailMap() == null ? null : order.getDetailMap().get(status);
				if (detailList != null) {
					detail = detailList.get(idx);
				}
			}
		} catch (Exception e) {
			log.warn(e);
		}
		writeJSON(detail);
	}

	public void saveModels() throws IOException {
		OrderDao dao = DaoFactory.getOrderDao();
		OrderBean order = (OrderBean) TRPUtil.getFromSession(TRPConstants.CURRENT_ORDER);
		Integer wfStatus = (Integer) TRPUtil.getFromSession(TRPConstants.CURRENT_MODEL_STATUS);
		long orderId = dao.saveOrder(order, wfStatus);
		// restore the sample info and matrix info from cache when it created
		// from template
		List<OrderBean.SampleInfo> sampleInfo = order.getSampleInfoList();
		List<OrderBean.MatrixInfo> matrixInfo = order.getMatrixInfoList();
		order = dao.getOrder(orderId);
		ResultMessage msg = new ResultMessage();
		if (order != null) {
			if (order.getSampleInfoList() == null || order.getSampleInfoList().isEmpty()) {
				order.setSampleInfoList(sampleInfo);
			}
			if (order.getMatrixInfoList() == null || order.getMatrixInfoList().isEmpty()) {
				order.setMatrixInfoList(matrixInfo);
			}
			TRPUtil.putToSession(TRPConstants.CURRENT_ORDER, order);
			msg.setState(ResultMessage.SUCCESS);
		} else {
			msg.setState(ResultMessage.FAILED);
		}
		writeJSON(msg);
	}

	public void updateModelData() throws IOException {
		boolean flag = false;
		try {
			int idx = getModelIdx(modelIdx);
			ModelDetail detail = getModelDetail(idx);
			ModelBean model = getModel(idx);
			// set status
			if (model != null) {
				int modelStatus = 0;
				try {
					String modelStatusStr = getParamFromRequest("modelStatus");
					modelStatus = Integer.parseInt(modelStatusStr);
				} catch (NumberFormatException e) {

				}
				model.setStatus(modelStatus);
			}
			if (detail != null) {
				List<ModelDetail.ModelSection> sectionList = detail.getSectionList();
				if (sectionList != null && !sectionList.isEmpty()) {
					for (ModelDetail.ModelSection section : sectionList) {
						List<ModelDetail.Field> fieldList = section.getFieldList();
						for (ModelDetail.Field field : fieldList) {
							field.setSelectedValue(getFieldValue(field, model.getClientUniqueId()));
						}
					}
				}
			}
			flag = true;
		} catch (Exception e) {
			log.warn(e);
		}
		ResultMessage msg = new ResultMessage();
		msg.setState(flag ? ResultMessage.SUCCESS : ResultMessage.FAILED);
		writeJSON(msg);
	}

	private String getFieldValue(ModelDetail.Field field, String uniqueId) {
		StringBuilder value = new StringBuilder();
		value.append(trimValue(getParamFromRequest("p" + uniqueId + field.getFieldId())));
		String fieldValue = value.toString();
		try {
			fieldValue = URLDecoder.decode(fieldValue, "UTF-8");
		} catch (Exception e) {
			log.warn(e);
		}
		return fieldValue;
	}

	private int getModelIdx(String modelIdx) {
		int idx = 0;
		if (!StringUtils.isEmpty(modelIdx)) {
			idx = Integer.parseInt(modelIdx);
		}
		return idx;
	}

	public void getTemplate() throws IOException {
		ModelDao dao = DaoFactory.getModelDao();
		String modelId = getParamFromRequest("modelId");
		String cate1 = getParamFromRequest("cate1");
		String cate2 = getParamFromRequest("cate2");
		try {
			List<TemplateBean> beanList = dao.getTemplate(Long.parseLong(modelId), cate1, cate2);
			writeJSON(beanList);
		} catch (NumberFormatException e) {
			log.warn(e);
		}
	}

}
